package com.ipan.poi.excel.config;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.ipan.kits.base.Platforms;
import com.ipan.kits.reflect.ClassLoaderUtil;

/**
 * 实体类格式配置
 * 
 * @author iPan
 * @version 2013-09-14
 */
public class XlsEntity implements Cloneable, Serializable {
	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 7603906956498997877L;
	// 常量
	public static final String ELE_ENTITY = "xlsEntity";
	public static final String PRO_CLASSNAME = "className";
	public static final String PRO_FILENAME = "fileName";
	/** 实体类类路径（唯一、不能为空） */
	private String className = "";
	/** 导入/导出文件名 */
	private String fileName = "";
	/** 字段集合 */
	private List<XlsProperty> properties = new ArrayList<XlsProperty>();
	/** 根元素 */
	private XlsRoot root = null;

	public XlsEntity(XlsRoot root, String className, String fileName) {
		this.root = root;
		this.className = className;
		this.fileName = fileName;
	}

	public XlsProperty getProperty(int index) {
		if (index > properties.size() - 1 || index < 0) {
			return null;
		}
		return this.properties.get(index);
	}
	
	public XlsProperty getProperty(String name) {
		if (properties == null) {
			return null;
		}
		XlsProperty result = null;
		for (XlsProperty pro : properties) {
			if (pro.getName().equals(name)) {
				result = pro;
				break;
			}
		}
		return result;
	}

	public void addProperty(XlsProperty field) {
		this.properties.add(field);
	}

	public void addProperty(String name, String title) {
		this.properties.add(new XlsProperty(this, name, title));
	}

	public List<XlsProperty> getProperties() {
		return this.properties;
	}

	public void setProperties(List<XlsProperty> fields) {
		this.properties = fields;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public XlsRoot getRoot() {
		return root;
	}

	public void setRoot(XlsRoot root) {
		this.root = root;
	}

	public int getPropertiesSize() {
		return this.properties.size();
	}
	
	public List<XlsProperty> getEnabledProperty() {
		if (this.properties == null) {
			return null;
		}
		List<XlsProperty> result = new ArrayList<XlsProperty>();
		for (XlsProperty pro : this.properties) {
			if (pro.isEnable()) {
				result.add(pro);
			}
		}
		return result;
	}
	
	public List<XlsProperty> getValidProperty() {
		if (this.properties == null) {
			return null;
		}
		List<XlsProperty> result = new ArrayList<XlsProperty>();
		for (XlsProperty pro : this.properties) {
			if (pro.isEnable() && pro.isValid()) {
				result.add(pro);
			}
		}
		return result;
	}
	
	public List<XlsProperty> getUnValidProperty() {
		if (this.properties == null) {
			return null;
		}
		List<XlsProperty> result = new ArrayList<XlsProperty>();
		for (XlsProperty pro : this.properties) {
			if (pro.isEnable() && !pro.isValid()) {
				result.add(pro);
			}
		}
		return result;
	}
	
	public List<XlsProperty> getSearchProperty() {
		if (this.properties == null) {
			return null;
		}
		List<XlsProperty> result = new ArrayList<XlsProperty>();
		for (XlsProperty pro : this.properties) {
			if (pro.isEnable() && StringUtils.isNotBlank(pro.getSearch())) {
				result.add(pro);
			}
		}
		return result;
	}

	@Override
	public XlsEntity clone() throws CloneNotSupportedException {
		XlsEntity cloneEntity = (XlsEntity) super.clone();
		List<XlsProperty> cloneFields = new ArrayList<XlsProperty>();
		cloneEntity.setProperties(cloneFields);
		// 复制字段集合
		List<XlsProperty> curFields = this.getProperties();
		if (curFields != null && curFields.size() > 0) {
			for (XlsProperty f : curFields) {
				cloneFields.add(f.clone());
			}
		}
		return cloneEntity;
	}

	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		buf.append("<").append(ELE_ENTITY).append(" ").append(PRO_CLASSNAME).append("=\"").append(className).append("\" ")
				.append(PRO_FILENAME).append("=\"").append(fileName).append("\">").append(Platforms.LINE_SEPARATOR);
		for (XlsProperty field : properties) {
			buf.append(field.toString());
		}
		buf.append("</").append(ELE_ENTITY).append(">").append(Platforms.LINE_SEPARATOR);
		return buf.toString();
	}
	
	/**
	 * 获取字段类型
	 */
	public Class<?> getPropertyType(String fieldName) {
		if (StringUtils.isBlank(this.className)) { // 为了满足，不是根据实体Bean导出的场景，手动创建XlsEntity，不需要对应的JavaBean；
			return String.class;
		}
		
		Class<?> entityClass = null;
		try {
			entityClass = ClassLoaderUtil.loadClass(this.className, this.getClass());
		} catch (ClassNotFoundException e) {
			throw new IllegalArgumentException("加载类：" + this.className + "出错！");
		}
		Field field = null;
		try {
			field = entityClass.getDeclaredField(fieldName);
		} catch (NoSuchFieldException e) {
			throw new IllegalArgumentException("类：" + this.className + "，加载字段：" + fieldName +  "时出错！");
		}
		return field.getType();
	}

}
